package com.ruoyi.back.service.impl

import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.ruoyi.app.common.*
import com.ruoyi.back.domain.SystemNotice
import com.ruoyi.back.domain.dto.SystemNoticeSearchDto
import com.ruoyi.back.domain.vo.SystemNoticeDetailVo
import com.ruoyi.back.domain.vo.SystemNoticeListVo
import com.ruoyi.back.enums.SendUserTypeEnum
import com.ruoyi.back.mapper.SystemNoticeMapper
import com.ruoyi.back.service.SystemNoticeParam
import com.ruoyi.back.service.SystemNoticeService
import com.ruoyi.back.service.UserSystemNoticeMessageService
import com.ruoyi.common.core.page.TableSupport
import com.ruoyi.scheduleTask.*
import org.quartz.Scheduler
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.util.*

@Service
class SystemNoticeServiceImpl : ServiceImpl<SystemNoticeMapper, SystemNotice>(), SystemNoticeService {

    @Autowired
    private lateinit var userSystemNoticeMessageService: UserSystemNoticeMessageService

    @Autowired
    private lateinit var scheduler: Scheduler


    override fun saveSystemNotice(systemNotice: SystemNotice): Data<Boolean> =
        systemNotice.id?.run {

            CommonUtil.removeJob(scheduler, this.toString(), GROUP)

            updateById(systemNotice)
            systemNotice.timingSend?.let { timingSend ->
                //发送定时任务
                scheduler.scheduleJob(SendUserMessageJob::class.java.jobDetail(this.toString()).run {
                    jobDataMap["type"] = systemNotice.sendUserType!!.sendUserType()!!
                    jobDataMap["param"] = systemNotice.covert()
                    this
                }, timingSend.parse().trigger(this.toString()))
                scheduler.start()

            }
            Ok("修改系统消息成功",true)
        } ?: kotlin.run {

            save(systemNotice)
            systemNotice.timingSend?.let { timingSend ->
                //发送定时任务
                scheduler.scheduleJob(SendUserMessageJob::class.java.jobDetail(systemNotice.id.toString()).run {
                    jobDataMap["type"] = systemNotice.sendUserType!!.sendUserType()!!
                    jobDataMap["param"] = systemNotice.covert()
                    this
                }, timingSend.parse().trigger(systemNotice.id.toString()))
                scheduler.start()
            }

            Ok("保存系统消息成功", true)
        }

    override fun systemNoticePage(systemNoticeSearchDto: SystemNoticeSearchDto): PageData<SystemNoticeListVo> =
        TableSupport.buildPageRequest().let { pageDomain ->
            page(
                Page(pageDomain.pageNum.toLong(), pageDomain.pageSize.toLong()),
                KtQueryWrapper(SystemNotice::class.java)
                    .eq(
                        StrUtil.isNotBlank(systemNoticeSearchDto.searchParam),
                        SystemNotice::title,
                        systemNoticeSearchDto.searchParam
                    )
                    .or().eq(
                        StrUtil.isNotBlank(systemNoticeSearchDto.searchParam),
                        SystemNotice::content,
                        systemNoticeSearchDto.searchParam
                    )
                    .gt(
                        StrUtil.isNotBlank(systemNoticeSearchDto.sendBeginTime),
                        SystemNotice::sendTime,
                        systemNoticeSearchDto.sendBeginTime.date()
                    )
                    .lt(
                        StrUtil.isNotBlank(systemNoticeSearchDto.sendEndTime),
                        SystemNotice::sendTime,
                        systemNoticeSearchDto.sendEndTime.date()
                    )
                    .eq(
                        systemNoticeSearchDto.sendUserType != null,
                        SystemNotice::sendUserType,
                        systemNoticeSearchDto.sendUserType
                    )
                    .orderByDesc(SystemNotice::sendTime)
            ).let { page: Page<SystemNotice> ->

                Page<SystemNoticeListVo>().apply {
                    BeanUtil.copyProperties(page, this)
                    records = page.records.takeIf { it.isNotEmpty() }?.run {
                        map {
                            SystemNoticeListVo().apply {
                                BeanUtil.copyProperties(it, this)
                                sendUserTypeStr = it.sendUserType?.sendUserTypeStr()
                                isTimingSend = it.timingSend?.run { true } ?: false
                                timingSend?.run {
                                    sendTime = this
                                }
                                sendTime = it.sendTime?.format()
                            }
                        }
                    }
                }.pageInfo()
            }
        }

    override fun removeSystemNoticeSend(ids: String): Data<Boolean> =
        Ok("批量移除定时任务成功", kotlin.run {
            ids.split(",").forEach {
                CommonUtil.removeJob(scheduler, it, GROUP)
                removeById(it)
            }
            true
        })

    override fun systemNoticeDetail(id: Long): Data<SystemNoticeDetailVo> =
        getById(id)?.let {
            Ok("获取详情信息成功", SystemNoticeDetailVo().apply {
                BeanUtil.copyProperties(it, this)
                sendUserType = if (it.sendUserType == SendUserTypeEnum.SINGLE_USER.code)
                    "${it.sendUserType?.sendUserTypeStr()}(ID:${it.singleUserId})" else
                    it.sendUserType?.sendUserTypeStr()
            })
        } ?: Fail("暂无该资源!")

    override fun systemNoticeSend(systemNotice: SystemNotice): Data<Boolean> =
        (systemNotice.id?.run { getById(this) } ?: systemNotice)
            .let { notice ->
                Ok("发送成功", kotlin.run {

                    notice.id?.run {
                        notice.run {
                            userSystemNoticeMessageService.sendUserSystemNoticeMessage(
                                sendUserType!!.sendUserType()!!,
                                covert()
                            )
                            updateById(notice.apply {
                                sendTime = Date()
                                send = true
                            })
                            CommonUtil.removeJob(scheduler, systemNotice.id.toString(), GROUP)
                        }
                    } ?: kotlin.run {
                        notice.timingSend = null
                        save(notice)
                        notice.run {
                            userSystemNoticeMessageService.sendUserSystemNoticeMessage(
                                sendUserType!!.sendUserType()!!,
                                covert()
                            )
                            updateById(notice.apply {
                                sendTime = Date()
                                send = true
                            })
                        }
                    }
                    true
                })

            }

    fun SystemNotice.covert(): SystemNoticeParam = SystemNoticeParam().apply {
        BeanUtil.copyProperties(this@covert, this)
        systemNoticeId = this@covert.id
    }

}